<template>
	<div class="upload-container">
		<el-upload
			ref="upload"
			class="upload-demo"
			action="#"
			accept=".jpg,.png"
			:show-file-list="false"
			:auto-upload="false"
			:limit="limit"
			:multiple="false"
			:disabled="fileList.length >= limit"
			:file-list="fileList"
			:on-change="handleChange"
		>
			<div v-for="(item, index) in fileList" :key="item.url" class="picBox" @click.stop>
				<el-image
					style="width: 180px; height: 180px"
					class="upload-img"
					:src="item.url"
					:preview-src-list="[item.url]"
					fit="contain"
				/>
				<i class="el-icon-close" @click.stop="handleRemove(index)" />
			</div>
			<i v-show="fileList.length < limit" class="el-icon-plus picBox" />
			<div slot="tip" class="el-upload__tip">
				*图片大小不得大于{{ maxSize }}M，格式仅支持JPG、PNG，最多可上传{{ limit }}张图片；
				<span v-if="imgWidth && imgHeight">图片尺寸限制为{{ imgWidth }}px*{{ imgHeight }}px</span>
				<span v-else-if="imgWidth">图片尺寸限制为宽度{{ imgWidth }}px或其倍数</span>
			</div>
		</el-upload>
	</div>
</template>

<script>
	export default {
		name: 'single-image-upload',
		props: {
			limit: {
				type: Number,
				default: 1
			},
			maxSize: {
				type: Number,
				default: 2
			},
			files: {
				type: Array,
				default() {
					return []
				}
			},
			current: {
				type: Number,
				default: 0
			},
			imgWidth: {
				type: Number,
				default: 0
			},
			imgHeight: {
				type: Number,
				default: 0
			}
		},
		data() {
			return {
				fileList: [],
				maxLength: 1
			}
		},
		watch: {
			files: {
				immediate: true,
				deep: true,
				handler(list) {
					this.fileList = list || []
				}
			}
		},
		methods: {
			// 上传了新文件
			handleChange(file, fileList) {
				// 多选图片加载到最大数量再执行操作
				const curLength = fileList.length
				this.maxLength = Math.max(curLength, this.maxLength)
				setTimeout(async () => {
					if (curLength !== this.maxLength) return
					this.maxLength = 0
					const list = []
					for (let i = 0; i < fileList.length; i++) {
						const { raw } = fileList[i]
						if (raw) {
							const fileType = raw.type === 'image/jpeg' || raw.type === 'image/png'
							const isSize = raw.size / 1024 / 1024 < this.maxSize
							if (!fileType || !isSize) {
								this.$message.error(
									!fileType
										? '文件类型只支持jpg/png！'
										: `上传图片文件大小不能超过${this.maxSize}MB！`
								)
								this.fileList = list
								return
							}
							fileList[i].name = this.MathRand() + '_' + raw.name
							fileList[i].url = URL.createObjectURL(raw)
							const image = new Image()
							image.src = fileList[i].url
							var promise = new Promise(reslove => {
								image.onload = async () => {
									const { width, height } = image
									if (
										this.imgWidth &&
										this.imgHeight &&
										(width !== this.imgWidth || height !== this.imgHeight)
									) {
										this.$message.error(`图片尺寸限制为${this.imgWidth}px*${this.imgHeight}px!`)
									} else if (this.imgWidth && !this.imgHeight && width % this.imgWidth > 0) {
										this.$message.error(`图片宽度为${this.imgWidth}px或其倍数!`)
									} else {
										file.index = fileList.length - 1
										list.push(fileList[i])
									}
									this.fileList = list
									reslove()
								}
							})
							await promise
							this.$emit('files', this.fileList, this.current)
						} else {
							list.push(fileList[i])
							this.fileList = list
							this.$emit('files', this.fileList, this.current)
						}
					}
				}, 0)
			},
			MathRand() {
				var Num = ''
				for (var i = 0; i < 8; i++) {
					Num += Math.floor(Math.random() * 10)
				}
				return Num
			},
			handleRemove(index) {
				this.fileList.splice(index, 1)
				this.$emit('files', this.fileList, this.current)
			}
		}
	}
</script>

<style lang="scss" scoped>
	@import '~@/styles/mixin.scss';
	.upload-container {
		width: 100%;
		position: relative;
		@include clearfix;
		.image-uploader {
			width: 60%;
			float: left;
		}
	}
	.picBox {
		position: relative;
		font-size: 28px;
		color: #8c939d;
		width: 180px;
		line-height: 180px;
		text-align: center;
		border: 1px dashed #d9d9d9;
		border-radius: 6px;
		cursor: pointer;
		position: relative;
		margin: 0 10px 10px 0;
		&:hover {
			border-color: #409eff;
		}
		::v-deep {
			.el-icon-close {
				font-size: 13px;
				position: absolute;
				top: 0;
				right: 0;
				z-index: 99;
				color: #fff;
				padding: 3px;
				background-color: #aaa;
				border-radius: 50%;
				box-shadow: 0 0 6px #666;
			}
		}
		.upload-img {
			width: 100%;
			display: block;
		}
	}
	.tip-warn {
		color: #333;
		font-size: 12px;
		padding: 6px 10px;
		line-height: 20px;
		border: 1px solid #fcd68b;
		border-radius: 2px;
		background: #fef2db;
		margin: 0 0 16px;
		display: flex;
		.el-icon-info {
			color: #faae17;
			margin: 4px 6px 0 0;
			display: inline-block;
		}
	}
	::v-deep {
		.upload-demo,
		.el-upload {
			display: flex;
			flex-wrap: wrap;
		}
		.upload-demo .el-upload {
			width: auto;
			text-align: left;
		}
		.el-image__inner {
			width: 98%;
		}
		.el-upload__tip {
			width: 100%;
			margin: 0;
			color: #5390f9;
			line-height: 18px;
		}
		.dialog-footer {
			margin-top: 50px;
			.el-button {
				width: 100px;
			}
		}
	}
</style>
